#include "HiVideoCapture.h"
#include <string>
#include "hi_mapi_vcap.h"
#include "hi_mapi_vproc.h"
#include "hi_mapi_sys.h"
#include "HiMediaSystem.h"


HiVideoCapture::HiVideoCapture()
    : mVpssHdl(0), mVCapDev(0), mVCapPipe(0), mPipeChn(0)
{
}

HiVideoCapture::~HiVideoCapture()
{
}

HI_S32 HiVideoCapture::Open(HI_HANDLE vpssHdl, HI_HANDLE vcapPipe, HI_U32 width, HI_U32 height)
{
    mVpssHdl = vpssHdl;
    mVCapPipe = vcapPipe;
    mPreviewWidth = width;
    mPreviewHeight = height;
    HI_S32 ret= HI_SUCCESS;
    ret |= OpenVI();
    ret |= OpenVPSS();
    return ret;
}

HI_S32 HiVideoCapture::Close(HI_VOID)
{
    HI_S32 ret= HI_SUCCESS;
    ret |= CloseVPSS();
    ret |= CloseVI();
    return ret;
}

HI_S32 HiVideoCapture::OpenVI(HI_VOID)
{

    HI_MAPI_VCAP_PIPE_ATTR_S vcapPipeAttr;
    memset(&vcapPipeAttr, 0x00, sizeof(vcapPipeAttr));
    vcapPipeAttr.stFrameRate.s32SrcFrameRate = -1;
    vcapPipeAttr.stFrameRate.s32DstFrameRate = -1;
    vcapPipeAttr.enCompressMode = COMPRESS_MODE_NONE;
    vcapPipeAttr.bIspBypass = HI_FALSE;
    vcapPipeAttr.enPipeBypassMode = VI_PIPE_BYPASS_NONE;
    vcapPipeAttr.stIspPubAttr.f32FrameRate = 30.0f;
    vcapPipeAttr.stIspPubAttr.stSize.u32Width = mPreviewWidth;
    vcapPipeAttr.stIspPubAttr.stSize.u32Height = mPreviewHeight;
    vcapPipeAttr.stIspPubAttr.enBayer = BAYER_RGGB;
    vcapPipeAttr.stFrameIntAttr.enIntType = FRAME_INTERRUPT_START;

    HI_MAPI_PIPE_CHN_ATTR_S pipeChnAttr;
    memset(&pipeChnAttr, 0x00, sizeof(pipeChnAttr));
    pipeChnAttr.stDestSize.u32Width = mPreviewWidth;
    pipeChnAttr.stDestSize.u32Height = mPreviewHeight;
    pipeChnAttr.stFrameRate.s32SrcFrameRate = 30;
    pipeChnAttr.stFrameRate.s32DstFrameRate = 30;
    pipeChnAttr.enCompressMode = COMPRESS_MODE_NONE;
    pipeChnAttr.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;

    /* ************************start vcap ***************************** */
    HI_MAPI_VCAP_ATTR_S vcapAttr;
    HI_MAPI_SENSOR_ATTR_S sensorAttr;

    memset(&sensorAttr, 0x00, sizeof(sensorAttr));
    memset(&vcapAttr, 0x00, sizeof(vcapAttr));
    /* sensor0 and media cfg */
    sensorAttr.u32SnsMode = 0;
    sensorAttr.enWdrMode = WDR_MODE_NONE;
    sensorAttr.stSize.u32Width = mPreviewWidth;
    sensorAttr.stSize.u32Height = mPreviewHeight;
    sensorAttr.stInputDevAttr.inputMode = INPUT_MODE_MIPI;
    sensorAttr.stInputDevAttr.inputDataType = DATA_TYPE_RAW_12BIT;

    HI_MAPI_VCAP_DEV_ATTR_S vcapDevAttr;
    memset(&vcapDevAttr, 0x00, sizeof(vcapDevAttr));
    vcapDevAttr.stBasSize.u32Width = mPreviewWidth;
    vcapDevAttr.stBasSize.u32Height = mPreviewHeight;
    vcapDevAttr.stWDRAttr.enWDRMode = WDR_MODE_NONE;
    vcapDevAttr.enIntfMode = VI_MODE_MIPI;
    vcapDevAttr.enInputDataType = VI_DATA_TYPE_RGB;
    if (sensorAttr.stInputDevAttr.inputDataType == DATA_TYPE_RAW_10BIT) {
        vcapDevAttr.au32ComponentMask[0] = 0xFFC00000;
        vcapDevAttr.au32ComponentMask[1] = 0;
    } else if (sensorAttr.stInputDevAttr.inputDataType == DATA_TYPE_RAW_12BIT) {
        vcapDevAttr.au32ComponentMask[0] = 0xFFF00000;
        vcapDevAttr.au32ComponentMask[1] = 0;
    } else {
        printf("other vcap dev attr ComponentMask has not be adapt yet\n");
    }


    /* dev0 attr */
    memcpy(&vcapAttr.stVcapDevAttr, &vcapDevAttr, sizeof(HI_MAPI_VCAP_DEV_ATTR_S));
    vcapAttr.u32PipeBindNum = 1;
    vcapAttr.aPipeIdBind[0] = mVCapPipe;

    /* Pipe0 attr */
    memcpy(&vcapAttr.astVcapPipeAttr[mVCapPipe], &vcapPipeAttr, sizeof(HI_MAPI_VCAP_PIPE_ATTR_S));
    vcapAttr.astVcapPipeAttr[mVCapPipe].enPipeType = HI_MAPI_PIPE_TYPE_VIDEO;

    /* Chn0 attr */
    memcpy(&vcapAttr.astVcapPipeAttr[mVCapPipe].astPipeChnAttr[mPipeChn], &pipeChnAttr,
           sizeof(HI_MAPI_PIPE_CHN_ATTR_S));

    /* Pipe2 attr */
    memcpy(&vcapAttr.astVcapPipeAttr[2], &vcapPipeAttr, sizeof(HI_MAPI_VCAP_PIPE_ATTR_S));
    vcapAttr.astVcapPipeAttr[2].enPipeType = HI_MAPI_PIPE_TYPE_VIDEO;

    /* Pipe2 Chn0 attr */
    memcpy(&vcapAttr.astVcapPipeAttr[2].astPipeChnAttr[mPipeChn], &pipeChnAttr,
           sizeof(HI_MAPI_PIPE_CHN_ATTR_S));

    /* vcap dev0 */
    HI_MAPI_VCAP_InitSensor(mVCapDev, &sensorAttr,HI_TRUE);
    HI_MAPI_VCAP_SetAttr(mVCapDev, &vcapAttr);
    HI_MAPI_VCAP_StartDev(mVCapDev);
    HI_MAPI_VCAP_StartChn(mVCapPipe, mPipeChn);
    HI_MAPI_VCAP_InitISP(mVCapPipe);
    HI_MAPI_VCAP_StartISP(mVCapPipe);
    HI_MAPI_VCAP_StartPipe(mVCapPipe);
    return HI_SUCCESS;
}

HI_S32 HiVideoCapture::CloseVI(HI_VOID)
{
    HI_MAPI_VCAP_StopPipe(mVCapPipe);
    HI_MAPI_VCAP_StopISP(mVCapPipe);
    HI_MAPI_VCAP_DeInitISP(mVCapPipe);
    HI_MAPI_VCAP_StopChn(mVCapPipe, mPipeChn);
    HI_MAPI_VCAP_StopDev(mVCapDev);
    HI_MAPI_VCAP_DeinitSensor(mVCapDev);

    return HI_SUCCESS;
}

HI_S32 HiVideoCapture::OpenVPSS(HI_VOID)
{
    HI_MAPI_VPROC_BindVcap(mVCapPipe, mPipeChn, mVpssHdl);
    return HI_SUCCESS;
}

HI_S32 HiVideoCapture::CloseVPSS(HI_VOID)
{
    HI_MAPI_VPROC_UnBindVCap(mVCapPipe, mPipeChn, mVpssHdl);
    return HI_SUCCESS;
}
